<template>
	<view :style="{'margin-top':marginTop+'rpx'}">
		<view v-if="loading">
			<block v-for="(item, index) in elements" :key="index">
				<!-- 横向并列布局 -->
				<view class="ls_skeleton-group" v-if="item.type=='flex'">
					<view :class="[inner.clas, index2>0?'ls_ml':'']" v-for="(inner, index2) in item.children" :key="index2">
						<view :class="[el.clas, el.clas=='ls_circle'?'':style, animateClass]" v-for="(el, index3) in inner.eles" :key="index3" ref="skeleton"></view>
					</view>
				</view>
				<!-- 扩展模板：新闻资讯模板 -->
				<!-- ps 自定义扩展说明： -->
				<!-- 如果你需要自定义模板，可以参照这个news的写法，增加一个skeleton配置类型，编写布局和样式就可以了 -->
				<!-- 注意事项：为了保证骨架效果和动态效果的一致，扩展时，在你希望实际展示在页面中的元素上加上 :class="[style, animateClass]" 和 ref="skeleton" -->
				<!-- 扩展-商户列表 -->
				<view class="list-merchant" v-else-if="item.type=='list_merchant'">
					<template v-for="(item2,index2) in 4" :key="index2">
						<view class="item">
							<view class="row row1">
								<view class="avatar" :class="[style, animateClass]" ref="skeleton"></view>
								<view class="info">
									<view class="t" :class="[style, animateClass]" ref="skeleton"></view>
									<view class="b" :class="[style, animateClass]" ref="skeleton"></view>
								</view>
							</view>
							<view class="row row2">
								<view class="tag" :class="[style, animateClass]" ref="skeleton"></view>
								<view class="tag" :class="[style, animateClass]" ref="skeleton"></view>
								<view class="tag" :class="[style, animateClass]" ref="skeleton"></view>
								<view class="tag" :class="[style, animateClass]" ref="skeleton"></view>
							</view>
							<view class="row row3" :class="[style, animateClass]" ref="skeleton"></view>
						</view>
					</template>
				</view>
				<!-- 扩展-服务列表 -->
				<view class="list-service" v-else-if="item.type=='list_service'">
					<template v-for="(item2,index2) in 4" :key="index2">
						<view class="item">
							<view class="img" :class="[style, animateClass]" ref="skeleton"></view>
							<view class="info">
								<view class="row1" :class="[style, animateClass]" ref="skeleton"></view>
								<view class="row2">
									<view class="tag" :class="[style, animateClass]" ref="skeleton"></view>
									<view class="tag" :class="[style, animateClass]" ref="skeleton"></view>
									<view class="tag" :class="[style, animateClass]" ref="skeleton"></view>
								</view>
								<view class="row3" :class="[style, animateClass]" ref="skeleton"></view>
							</view>
						</view>
					</template>
				</view>
				<!-- 扩展-我的页面推荐行业大牛 -->
				<view class="mine-recommoned" v-else-if="item.type=='mine_recommoned'">
					<view class="hd" :class="[style, animateClass]" ref="skeleton"></view>
					<view class="bd">
						<view class="item" v-for="(item2,index2) in 2" :key="index2">
							<view class="avatar" :class="[style, animateClass]" ref="skeleton"></view>
							<view class="info">
								<view class="row1" :class="[style, animateClass]" ref="skeleton"></view>
								<view class="row2" :class="[style, animateClass]" ref="skeleton"></view>
							</view>
						</view>
					</view>
					<view class="ft" :class="[style, animateClass]" ref="skeleton"></view>
				</view>
				<!-- 扩展-我的页面最新悬赏 -->
				<view class="mine-needs" v-else-if="item.type=='mine_needs'">
					<view class="hd" :class="[style, animateClass]" ref="skeleton"></view>
					<view class="bd">
						<view class="item" v-for="(item2,index2) in 2" :key="index2">
							<view class="title" :class="[style, animateClass]" ref="skeleton"></view>
							<view class="ft">
								<view class="state" :class="[style, animateClass]" ref="skeleton"></view>
								<view class="time" :class="[style, animateClass]" ref="skeleton"></view>
							</view>
						</view>
					</view>
				</view>
				<!-- 垂直高度站位 -->
				<view :style="{height: item.height+'rpx'}" v-else-if="item.type=='space'"></view>
				<!-- 其他基本单位  line  card circle 等 -->
				<view :class="[item.clas, item.clas=='ls_circle'?'':style, animateClass]" v-else ref="skeleton"></view>
			</block>
		</view>
		<view v-else style="flex: 1;width: 750rpx;">
			<slot />
		</view>
	</view>
</template>
<script>
	import {
		getElCountsAndLayout,
		getElCounts
	} from './util';
	// #ifdef APP-NVUE
	const animationActuator = weex.requireModule('animation');
	let interval;
	// #endif
	/**
	 * ls-skeleton 骨架屏
	 * @description 可自定义内容的骨架屏
	 * @property {Boolean} loading 是否显示骨架（默认：否）
	 * @property {Boolean} round 是否圆角骨架风格（默认：否）
	 * @property {Boolean} animate 是否开启动画效果（默认：是）
	 * @property {Array} skeleton 骨架内容 （段落：line|line-sm|line-lg| 卡片：card|card-sm|card-lg| 圆：circle|circle-sm|circle-lg 正方形：square|square-sm|square-lg）个数标识符*  横向并列连接标识符+
	 * @example 
	 * <ls-skeleton :skeleton="skeleton" :loading="loading">
	 * 	<view>好的，页面加载完了</view>
	 * </ls-skeleton>
	 */
	export default {
		name: 'ls-skeleton',
		props: {
			// 是否显示骨架
			loading: {
				type: Boolean,
				default: true
			},
			// 是否圆角骨架风格
			round: {
				type: Boolean,
				default: false
			},
			// 骨架内容 特殊符号说明 [*代表个数 例如：line*3 意思是3个行] [+代表横向并列排列连接  例如：circ+line 意思是左侧一个圆右侧一个行] [纯数字 代表垂直间隔 例如：40 代表40前后的两个元素之间有40rpx高度的间隔]
			skeleton: {
				type: Array,
				default: () => []
			},
			// 是否开启动画效果
			animate: {
				type: Boolean,
				default: true
			},
			// 整体偏移距离
			marginTop: {
				type: [Number],
				default: 0
			}
		},
		data() {
			return {
				elements: []
			}
		},
		computed: {
			animateClass() {
				return this.animate ? 'ls_animation' : 'ls_static';
			},
			style() {
				if (this.round) {
					return 'ls_round';
				}
				return 'ls_radius';
			},
			winHeight() {
				return uni.getSystemInfoSync().windowHeight;
			}
		},
		watch: {
			// 开始loading时，加载动画
			loading(val) {
				// #ifdef APP-NVUE
				if (val && this.animate) {
					this.createAnimation();
				}
				// #endif
			}
		},
		created() {
			this.init();
			// #ifdef APP-NVUE
			if (this.loading && this.animate) {
				setTimeout(() => {
					this.createAnimation();
				}, 40);
			}
			// #endif
		},
		methods: {
			init() {
				let elements = [];
				let elClass;
				this.skeleton.forEach(el => {
					if (typeof(el) === 'string') {
						if (el.indexOf("+") > -1) {
							let group = el.split("+");
							let children = [];
							group.forEach(els => {
								children.push(getElCountsAndLayout(els));
							});
							elements.push({
								type: 'flex',
								children: children
							});
						} else if (el === 'recommend') {
							elements.push({
								type: 'recommend',
								height: el
							});
						} else if (el.indexOf("list") > -1 && el.indexOf("-") > -1) {
							// show_type:1-全部显示 2-不显示tab,下面的全部显示 3-tab不显示,title下面的只显示一行
							let show_type = el.split("-")[1];
							elements.push({
								type: 'list',
								show_type: show_type
							});
						} else if (el.indexOf("balance") > -1 && el.indexOf("-") > -1) {
							// show_type:1-全部显示 2-不显示tab
							let show_type = el.split("-")[1];
							elements.push({
								type: 'balance',
								show_type: show_type
							});
						} else {
							elClass = getElCounts(el);
							elements = elements.concat(elClass);
						}
					} else if (typeof(el) === 'number') {
						elements.push({
							type: 'space',
							height: el
						});
					} else {
						console.warn("[ls-skeleton]: 参数格式包含了不符合规范的内容");
					}
				});
				this.elements = [...elements];
			},
			createAnimation() {
				let background = '#e6e6e6';
				clearInterval(interval);
				interval = setInterval(() => {
					background = background === '#e6e6e6' ? '#d3d3d3' : '#e6e6e6';
					this.executeAnimation(background);
				}, 1000);
			},
			executeAnimation(background) {
				// loading结束之后，移除计时器，动画不再执行
				if (!this.loading) {
					clearInterval(interval);
					return;
				}
				this.$refs.skeleton.forEach(item => {
					animationActuator.transition(item, {
						styles: {
							"backgroundColor": background,
						},
						duration: 800, //ms  
						timingFunction: 'linear'
					});
				})
			},
		}
	}
</script>
<style scoped lang="scss">
	@import url("css/index.css");
	/* 扩展模板news样式 */
	.ls_news {
		flex: 1;
		margin-left: 20rpx;
	}
	.ls_news_img {
		width: 240rpx;
		height: 200rpx;
		margin-bottom: 30rpx;
	}
	.ls_news_user {
		height: 32rpx;
		margin-bottom: 30rpx;
		width: 260rpx;
	}
	.ls_news_time {
		height: 32rpx;
		margin-bottom: 30rpx;
		width: 130rpx;
	}
	// 扩展-商家列表
	.list-merchant {
		.item {
			width: 100%;
			margin-bottom: 28rpx;
			padding: 30rpx 20rpx;
			border-radius: 18rpx;
			background-color: #fff;
			.row {
				display: flex;
				.avatar {
					width: 86rpx;
					height: 86rpx;
					border-radius: 50%;
				}
				.info {
					display: flex;
					flex: 1;
					flex-direction: column;
					justify-content: center;
					margin-left: 20rpx;
					.t {
						width: 100%;
						height: 40rpx;
					}
					.b {
						width: 100%;
						height: 32rpx;
						margin-top: 10rpx;
					}
				}
				&1 {
					height: 88rpx;
				}
				&2 {
					display: flex;
					justify-content: space-between;
					height: 60rpx;
					margin: 20rpx 0 10rpx;
					.tag {
						width: 150rpx;
						height: 48rpx;
					}
				}
				&3 {
					height: 40rpx;
				}
			}
		}
	}
	// 扩展-服务列表
	.list-service {
		.item {
			display: flex;
			width: 100%;
			margin-bottom: 28rpx;
			padding: 20rpx;
			border-radius: 18rpx;
			background-color: #fff;
			.img {
				width: 188rpx;
				height: 188rpx;
				margin-right: 20rpx;
			}
			.info {
				flex: 1;
			}
			.row1 {
				height: 80rpx;
			}
			.row2 {
				display: flex;
				justify-content: space-between;
				height: 44rpx;
				margin: 12rpx 0;
				.tag {
					width: 135rpx;
					height: 44rpx;
				}
			}
			.row3 {
				height: 40rpx;
			}
		}
	}
	// 扩展-我的页面推荐行业大牛
	.mine-recommoned {
		height: 392rpx;
		.hd {
			height: 40rpx;
		}
		.bd {
			.item {
				display: flex;
				align-items: center;
				padding: 34rpx 0;
				border-bottom: 1px solid #ddd;
				&:last-child {
					border-bottom: 0;
				}
			}
			.avatar {
				width: 86rpx;
				height: 86rpx;
				border-radius: 50%;
				margin-right: 20rpx;
			}
			.info {
				flex: 1;
				.row1 {
					height: 44rpx;
					margin-bottom: 8rpx;
				}
				.row2 {
					height: 32rpx;
				}
			}
		}
		.ft {
			height: 40rpx;
		}
	}
	// 扩展-我的页面推荐行业大牛
	.mine-needs {
		height: 276rpx;
		.hd {
			height: 40rpx;
			margin: 0 28rpx;
		}
		.bd {
			display: flex;
			padding: 30rpx 0 0;
			overflow: hidden;
		}
		.item {
			width: 494rpx;
			height: 204rpx;
			margin-left: 28rpx;
			padding: 22rpx;
			border: 1px solid #ECECEC;
			border-radius: 12rpx;
			.title {
				width: 448rpx;
				height: 76rpx;
			}
			.ft {
				display: flex;
				align-items: center;
				justify-content: space-between;
				margin-top: 30rpx;
			}
			.state {
				width: 120rpx;
				height: 48rpx;
			}
			.time {
				width: 180rpx;
				height: 32rpx;
			}
		}
	}
</style>
